package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.display.BlendMode;
	import flash.filters.BlurFilter;
	
	public class GasEffect extends Sprite
	{
		//VARIABLES INTERNAS SETEABLES OBLIGATORIAS.
			
			public var targetClip:Sprite;
			
		//VARIABLES INTERNAS SETEABLES OPCIONALES.
		
			public var noiseVel:Number = 2.5;
			public var noiseDir:Object = { x:0.5, y:1 };
			public var noiseWidth:Number = 15;
			public var noiseHeight:Number = 40;
			public var rTransform:Number = 0.8;
			public var gTransform:Number = 0.9;
			public var bTransform:Number = 0.98;
			public var aTransform:Number = 0.8;
			public var blurStrength:Number = 4;
			public var noiseOctaves:Number = 6;
			public var drawOverClip:Boolean = true;
			public var overClipAlpha:Number = 0.5;
			public var wOffset:uint = 50;
			public var hOffset:uint = 100;
		
		//VARIABLES INTERNAS.
			
			private var noiseHolder:Sprite = new Sprite();
			private var bmpDataHolder:Sprite = new Sprite();
			private var overHolder:Sprite = new Sprite();
			private var noiseHolderBmp:Bitmap = new Bitmap();
			private var bmpDataHolderBmp:Bitmap = new Bitmap();
			private var overHolderBmp:Bitmap = new Bitmap();
			private var W:Number;
			private var H:Number;
			private var noisePosition:Point = new Point();
		
		//CONSTRUCTOR.
		public function GasEffect()
		{
			
		}
		
		//INIT.
		public function init():void
		{
			//EXTRAE LAS DIMENSIONES.
			W = targetClip.width;
			H = targetClip.height;
			
			//ACOMODA LOS HOLDERS.
			bmpDataHolder.x -= wOffset / 2;
			bmpDataHolder.y -= hOffset / 2;
			noiseHolder.x -= wOffset / 2;
			noiseHolder.y -= hOffset / 2;
			
			//INICIALIZA LOS HOLDERS.
			targetClip.addChild(bmpDataHolder);
			targetClip.addChild(noiseHolder);
			noiseHolder.blendMode = BlendMode.OVERLAY;
			
			//INICIALIZA LOS BMPs.
			noiseHolder.addChild(noiseHolderBmp);
			bmpDataHolder.addChild(bmpDataHolderBmp);
			
			//DUPLICA EL CLIP INICIAL ENCIMA DE TODO.
			if(drawOverClip)
			{
				overHolder.alpha = overClipAlpha;
				overHolder.x -= wOffset / 2;
				overHolder.y -= hOffset / 2;
				targetClip.addChild(overHolder);
				overHolder.addChild(overHolderBmp);
				overClip();
			}
				
			
			//INICIA EL ENTERFRAME.
			addEventListener(Event.ENTER_FRAME, animation);
		}
		
		//ANIMACION.
		private function animation(evt:Event):void
		{
			//ACTUALIZA LA POSICION.
			noisePosition.x += noiseVel*noiseDir.x;
			noisePosition.y += noiseVel*noiseDir.y;
			
			//REDIBUJA EL COPYBMPHOLDER EN EL BLURREDBMPHOLDER, DESFAZANDOLO.
			redrawClip();
			
			//DIBUJA EL PERLIN.
			refreshPerlin();
		}
		
		//REDIBUJA EL CLIP.
		private function redrawClip():void
		{
			//REDIBUJA.
			var bmpData:BitmapData = new BitmapData(W + wOffset, H + hOffset, false, 0x00000);
			var mat:Matrix = new Matrix();
			mat.translate(wOffset/2, hOffset/2);
			bmpData.draw(targetClip, mat, new ColorTransform(rTransform, gTransform, bTransform, aTransform, 0, 0, 0, 0));
			
			//APLICA EL FILTRO.
			bmpData.applyFilter(bmpData, bmpData.rect, new Point(), new BlurFilter(blurStrength, blurStrength, 1));
			
			//DESFAZA LA IMAGEN.
			bmpData.scroll(-noiseVel*noiseDir.x, -noiseVel*noiseDir.y);
			
			//ACTUALIZA.
			bmpDataHolderBmp.bitmapData = bmpData;
		}
		
		//GENERA UN PERLIN NOISE.
		private function refreshPerlin():void
		{
			//INICIALIZA EL BITMAPDATA.
			var bmpData:BitmapData = new BitmapData(W + wOffset, H + hOffset, false, 0xFF0000);
			
			//DIBUJA EL RUIDO.
			bmpData.perlinNoise(noiseWidth, noiseHeight, noiseOctaves, 1 , false, true, 1, true, [noisePosition]);
		
			//ACTUALIZA.
			noiseHolderBmp.bitmapData = bmpData;
		}
		
		//REDIBUJA EL OVERCLIP.
		private function overClip():void
		{
			//REDIBUJA.
			var bmpData:BitmapData = new BitmapData(W + wOffset, H + hOffset, true, 0x0000000);
			var mat:Matrix = new Matrix();
			mat.translate(wOffset/2, hOffset/2);
			bmpData.draw(targetClip, mat);
			
			//ACTUALIZA.
			overHolderBmp.bitmapData = bmpData;
		}
	}
}